package svcnode.share;

import java.io.File;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

public class Cnfg
{
    private static String __CLASS__=Cnfg.class.getName();
    private static Cnfg instance=null;

    private static final int WORKER_DEF_NUM=4;
    private static final int WORKER_MAX_NUM=64;

    private Cnfg()
    {
    }

    public static synchronized Cnfg getInstance()
    {/*{{{*/
        if(instance == null)
        {
            instance=new Cnfg();
        }
        return instance;
    }/*}}}*/

    public class Log
    {
        public String location;
        public boolean tracking;
    }
    public Log log;

    public class Access
    {
        public int server_port;
        public int monitor_port;
    }
    public Access access;

    public class Netlog
    {
        public String location;
    }
    public Netlog netlog;

    public int workers;

    public class Session
    {
        public boolean enable;
        public long timeout;
    }
    public Session session;

    public boolean load()
    {/*{{{*/
        final String __METHOD_="load";

        Document doc;
        try
        {
            SAXBuilder builder=new SAXBuilder();
            doc=builder.build(new File("cnfg.xml"));
        }
        catch(Exception e)
        {
            System.out.println(String.format(
                        "%s.%s: load cnfg.xml fail: %s",
                        __CLASS__, __METHOD_, e.getMessage()));
            return false;
        }

        Element root=doc.getRootElement();
        Element section;
        String section_s;
        Element property;

        this.log=new Log();
        section=root.getChild("log"); 
        if(section == null)
        {
            System.out.println(String.format("%s.%s: get %s fail",
                    __CLASS__, __METHOD_, section.getName()));
            return false;
        }
        section_s="["+section.getName()+"]";
        property=section.getChild("location");
        if(property == null)
        {
            System.out.println(String.format("%s.%s: get %s.%s fail",
                    __CLASS__, __METHOD_,
                    section.getName(), property.getName()));
            return false;
        }
        this.log.location=property.getText();
        System.out.println(String.format("%s.%s: %s %s:%s",
                __CLASS__, __METHOD_, section_s,
                property.getName(), property.getText()));
        property=section.getChild("tracking");
        this.log.tracking=false;
        if(property != null)
        {
            String opt=property.getText().trim().toLowerCase();
            if(opt.equals("true") || opt.equals("yes") || opt.equals("1"))
                this.log.tracking=true;
        }
        System.out.println(String.format("%s.%s: %s %s:%s",
                __CLASS__, __METHOD_, section_s,
                property.getName(), property.getText()));

        this.access=new Access();
        section=root.getChild("access"); 
        if(section == null)
        {
            System.out.println(String.format("%s.%s: get %s fail",
                    __CLASS__, __METHOD_, section.getName()));
            return false;
        }
        section_s="["+section.getName()+"]";
        property=section.getChild("server_port");
        if(property == null)
        {
            System.out.println(String.format("%s.%s: get %s.%s fail",
                    __CLASS__, __METHOD_,
                    section.getName(), property.getName()));
            return false;
        }
        this.access.server_port=Integer.parseInt(property.getText());
        System.out.println(String.format("%s.%s: %s %s:%s",
                __CLASS__, __METHOD_, section_s,
                property.getName(), property.getText()));
        property=section.getChild("monitor_port");
        if(property == null)
        {
            System.out.println(String.format("%s.%s: get %s.%s fail",
                    __CLASS__, __METHOD_,
                    section.getName(), property.getName()));
            return false;
        }
        this.access.monitor_port=Integer.parseInt(property.getText());
        System.out.println(String.format("%s.%s: %s %s:%s",
                __CLASS__, __METHOD_, section_s,
                property.getName(), property.getText()));

        this.netlog=new Netlog();
        section=root.getChild("netlog"); 
        if(section == null)
        {
            System.out.println(String.format("%s.%s: get %s fail",
                    __CLASS__, __METHOD_, section.getName()));
            return false;
        }
        section_s="["+section.getName()+"]";
        property=section.getChild("location");
        if(property == null)
        {
            System.out.println(String.format("%s.%s: get %s.%s fail",
                    __CLASS__, __METHOD_,
                    section.getName(), property.getName()));
            return false;
        }
        this.netlog.location=property.getText().trim();
        System.out.println(String.format("%s.%s: %s %s:%s",
                __CLASS__, __METHOD_, section_s,
                property.getName(), property.getText()));

        property=root.getChild("workers"); 
        if(property == null)
        {
            this.workers=WORKER_DEF_NUM;
        }
        else
        {
            int workers=Integer.parseInt(property.getText());
            if(workers < WORKER_DEF_NUM || workers > WORKER_MAX_NUM)
                this.workers=WORKER_DEF_NUM;
            else
                this.workers=workers;
        }

        this.session=new Session();
        section=root.getChild("session"); 
        if(section == null)
        {
            System.out.println(String.format("%s.%s: get %s fail",
                    __CLASS__, __METHOD_, section.getName()));
            return false;
        }
        section_s="["+section.getName()+"]";
        property=section.getChild("enable");
        if(property == null)
        {
            System.out.println(String.format("%s.%s: get %s.%s fail",
                    __CLASS__, __METHOD_,
                    section.getName(), property.getName()));
            return false;
        }
        int enable=Integer.parseInt(property.getText());
        if(enable != 0)
            this.session.enable=true;
        else
            this.session.enable=false;
        System.out.println(String.format("%s.%s: %s %s:%s",
                __CLASS__, __METHOD_, section_s,
                property.getName(), property.getText()));
        property=section.getChild("timeout");
        if(property == null)
        {
            System.out.println(String.format("%s.%s: get %s.%s fail",
                    __CLASS__, __METHOD_,
                    section.getName(), property.getName()));
            return false;
        }
        this.session.timeout=Integer.parseInt(property.getText());
        System.out.println(String.format("%s.%s: %s %s:%s",
                __CLASS__, __METHOD_, section_s,
                property.getName(), property.getText()));

        return true;
    }/*}}}*/
}
